home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / asm / utils / cryptdevice / cryptdev.s < prev    next >
Text File  |  1980-01-03  |  27KB  |  1,549 lines

  1. ;
  2. ; cryptdev.a   --   created from fdev.device -- "filesystem in a file"
  3. ;
  4. ; 1992-10-14
  5. ;
  6. ; uses IDEA encryption algorithm
  7. ;
  8. ;
  9. ; created  1989-08-13  TR
  10. ;
  11. ; modifications:
  12. ;  1989-08-15  TR  -  added separate dos calling process
  13. ;  1989-08-16  TR  -  removed unit processes (all commands are IMMEDIATE...)
  14. ;  1989-08-19  TR  -  changed DosCaller parameter passing
  15. ;              also no longer need to RemTask a process
  16. ;              dos caller process messages now contain IORequest
  17. ;              pointer in LN_NAME field. zero LN_NAME field
  18. ;              means that the message is a request to quit
  19. ;              the DosCaller process.
  20. ;  1989-08-20  TR  -  now closes the file when requested to turn motor off
  21. ;  1989-08-31  TR  -  some small bugs fixed. AbortIO now returns an error.
  22. ;
  23. ;  1991-06-10  TR  -  Now properly clears IO_ERROR when there is no error.
  24. ;              Can now be assembled with standard include files.
  25. ;              Created Makefile (for PD Make & A68k)
  26. ;
  27.     incdir    coding:os2.0/include2.0/
  28.     include    'exec/exec_lib.i'
  29.     include    'exec/types.i'
  30.     include    'exec/initializers.i'
  31.     include    'exec/memory.i'
  32.     include    'exec/io.i'
  33.     include    'exec/devices.i'
  34.     include    'exec/resident.i'
  35.     include    'exec/errors.i'
  36.     include    'devices/trackdisk.i'
  37.     include    'libraries/dos.i'
  38.     include    'libraries/dos_lib.i'
  39.     include    'libraries/dosextens.i'
  40.     include    'intuition/intuition.i'
  41.     include    'intuition/intuition_lib.i'
  42. ;
  43. ; new library call macros
  44. ;
  45. lib        macro
  46.         jsr    _LVO\1(a6)
  47.         endm
  48.  
  49. rw        macro
  50.         dc.w    \1-*
  51.         endm
  52.  
  53. BLOCKSIZE    equ    512
  54. KS_SIZE        equ    216
  55.  
  56. ;
  57. ; the data structure of the device
  58. ;
  59.  
  60.     STRUCTURE CryptDevBase,LIB_SIZE
  61.      APTR    crd_SegList
  62.      APTR    crd_DosLib
  63.      APTR    crd_IntuitionBase
  64.      APTR    crd_DosCallerProc
  65.      APTR    crd_DosCallerPort
  66.      STRUCT    crd_DosCallerInitMsg,MN_SIZE
  67.      STRUCT    crd_UnitList,MLH_SIZE
  68.     LABEL crd_Sizeof
  69.  
  70. ;
  71. ; unit data structure. note that units are linked to the device
  72. ; structure using the crdu_Link field.
  73. ;
  74.     STRUCTURE CryptDevUnit,UNIT_SIZE
  75.      STRUCT    crdu_Link,MLN_SIZE    to link to units to a list
  76.      UWORD    crdu_UnitNum
  77.      LONG    crdu_FileHandle        zero if file not open
  78.      STRUCT    crdu_FileName,32
  79.      STRUCT crdu_KeySched,KS_SIZE
  80.      STRUCT    crdu_IVec,8
  81.      STRUCT    crdu_Buffer,BLOCKSIZE
  82.      UBYTE    crdu_KeyValid
  83.     LABEL crdu_Sizeof
  84.  
  85. DOSCALLERSTACK    equ    2000
  86. DOSCALLERPRI    equ    0
  87.  
  88. ;
  89. ; try to remember to increment the revision number...
  90. ;
  91. VERSION        equ    1
  92. REVISION    equ    8
  93.  
  94.  
  95.     section    text,CODE
  96.  
  97. ;
  98. ; start of code -- just return zero if someone executes this directly
  99. ; the Null-standard library routine points also here
  100. ;
  101. Null    moveq    #0,d0
  102.     rts
  103.  
  104. RomTag    dc.w    RTC_MATCHWORD
  105.     dc.l    RomTag
  106.     dc.l    EndSkip
  107.     dc.b    RTF_AUTOINIT
  108.     dc.b    VERSION
  109.     dc.b    NT_DEVICE
  110.     dc.b    0
  111.     dc.l    dev_name
  112.     dc.l    dev_idstring
  113.     dc.l    dev_init
  114.  
  115. dev_name    dc.b    'crypt.device',0
  116. dev_idstring    dc.b    'crypt 1.8 (TR 16-Oct-1992)',13,10,0
  117.  
  118. dosname        dc.b    'dos.library',0
  119. intuition_name    dc.b    'intuition.library',0
  120.  
  121. doscallername    dc.b    'CryptDev_DosCaller',0
  122.  
  123.     even
  124. ;
  125. ; because the RTF_AUTOINIT flag in the RomTag structure was set
  126. ; RT_INIT points to this table of parameters for MakeLibrary()
  127. ;
  128. dev_init
  129.     dc.l    crd_Sizeof
  130.     dc.l    dev_FuncInit
  131.     dc.l    dev_StructInit
  132.     dc.l    dev_InitRoutine
  133.  
  134. dev_StructInit
  135.     INITBYTE LN_TYPE,NT_DEVICE
  136.     INITLONG LN_NAME,dev_name
  137.     INITLONG LIB_IDSTRING,dev_idstring
  138.     INITBYTE LIB_FLAGS,LIBF_CHANGED!LIBF_SUMUSED
  139.     INITLONG LIB_VERSION,(VERSION<<16)+REVISION
  140.     dc.l    0
  141.  
  142. ;
  143. ; a simple macro to save typing in library routine definitions below
  144. ;
  145. fw    macro
  146.     dc.w    \1-dev_FuncInit
  147.     endm
  148.  
  149. dev_FuncInit
  150.     dc.w    -1
  151. ; standard system library routines
  152.     fw    Open
  153.     fw    Close
  154.     fw    Expunge
  155.     fw    Null
  156. ; standard device routines
  157.  
  158.     fw    BeginIO
  159.     fw    AbortIO
  160.  
  161. ; end of table marker
  162.     dc.w    -1
  163.  
  164. ;
  165. ; device command table
  166. ;
  167. DevCmdTable
  168.     rw    Invalid            CMD_INVALID
  169.     rw    ResetPassword        CMD_RESET
  170.     rw    DoRead            CMD_READ
  171.     rw    DoWrite            CMD_WRITE
  172.     rw    DoNothing        CMD_UPDATE
  173.     rw    DoNothing        CMD_CLEAR
  174.     rw    Invalid            CMD_STOP
  175.     rw    Invalid            CMD_START
  176.     rw    DoNothing        CMD_FLUSH
  177.     rw    DoMotor            TD_MOTOR
  178.     rw    DoNothing        TD_SEEK
  179.     rw    DoWrite            TD_FORMAT
  180.     rw    DoNothing        TD_REMOVE
  181.     rw    DoNothing        TD_CHANGENUM
  182.     rw    DoNothing        TD_CHANGESTATE
  183.     rw    DoNothing        TD_PROTSTATUS
  184.     rw    Invalid            TD_RAWREAD
  185.     rw    Invalid            TD_RAWWRITE
  186.     rw    DoGetDriveType        TD_GETDRIVETYPE
  187.     rw    DoGetNumTracks        TD_GETNUMTRACKS
  188.     rw    DoNothing        TD_ADDCHANGEINT
  189.     rw    DoNothing        TD_REMCHANGEINT
  190.  
  191. ;
  192. ; init routine, entry: d0=LibBase, a0=SegList, a6=ExecBase
  193. ; return: d0=LibBase if initialization is successfull, zero if failed
  194. ;
  195. dev_InitRoutine
  196.     move.l    a4,-(sp)
  197.     move.l    d0,a4            get library base in a4
  198.     move.l    a0,crd_SegList(a4)    save our seglist for expunge...
  199.  
  200. ;
  201. ; allocate and partially initialize the dos caller process message port
  202. ; the dos caller process initializes MP_SIGBIT and MP_SIGTASK fields
  203. ; and sets MP_FLAGS to PA_SIGNAL...
  204. ;
  205.     moveq    #MP_SIZE,d0
  206.     move.l    #MEMF_CLEAR!MEMF_PUBLIC,d1
  207.     lib    AllocMem
  208.     move.l    d0,crd_DosCallerPort(a4)
  209.     beq.w    initfail3
  210.     move.l    d0,a0
  211.     move.b    #PA_IGNORE,MP_FLAGS(a0)
  212.     lea    MP_MSGLIST(a0),a0
  213.     NEWLIST    a0
  214.  
  215.     lea    intuition_name(pc),a1
  216.     moveq    #33,d0
  217.     lib    OpenLibrary
  218.     move.l    d0,crd_IntuitionBase(a4)
  219.     beq.b    initfail2a
  220.  
  221.     lea    dosname(pc),a1
  222.     moveq    #33,d0
  223.     lib    OldOpenLibrary
  224.     move.l    d0,crd_DosLib(a4)
  225.     beq.s    initfail2
  226.     move.l    a6,-(sp)
  227.     move.l    d0,a6
  228.  
  229.     move.l    #DOSCALLERSTACK,d4
  230.     lea    doscallerseglist(pc),a0
  231.     move.l    a0,d3
  232.     lsr.l    #2,d3            convert to BPTR
  233.     moveq    #DOSCALLERPRI,d2
  234.     lea    doscallername(pc),a0
  235.     move.l    a0,d1
  236.     lib    CreateProc
  237.     move.l    (sp)+,a6
  238.     move.l    d0,crd_DosCallerProc(a4)
  239.     tst.l    d0
  240.     beq.s    initfail1
  241.  
  242. ;
  243. ; send startup message to the dos caller process
  244. ;
  245.     move.l    d0,a0
  246.     lea    crd_DosCallerInitMsg(a4),a1
  247.     move.l    a4,LN_NAME(a1)
  248.     lib    PutMsg
  249.  
  250.     lea    crd_UnitList(a4),a0
  251.     NEWLIST    a0
  252.  
  253.     move.l    a4,d0
  254.     bra.s    init9
  255.  
  256. initfail1
  257.     move.l    crd_DosLib(a4),a1
  258.     move.l    4.w,a6
  259.     jsr    _LVOCloseLibrary(a6)
  260. initfail2
  261.     move.l    crd_IntuitionBase(a4),a1
  262.     move.l    4.w,a6
  263.     jsr    _LVOCloseLibrary(a6)
  264. initfail2a
  265.     move.l    crd_DosCallerPort(a4),a1
  266.     moveq    #MP_SIZE,d0
  267.     lib    FreeMem
  268. initfail3
  269.     moveq    #0,d0
  270.  
  271. init9    move.l    (sp)+,a4
  272.     rts
  273.  
  274. ;
  275. ; open routine, entry: a6=DevBase, a1=IORequest, d0=UnitNum, d1=Flags
  276. ; return: d0=zero or error code
  277. ;
  278. Open    movem.l    d2/a2-a4,-(sp)
  279.     move.l    a1,a2
  280.  
  281.     move.l    d0,d2        save unit number
  282.     bsr.w    FindUnit
  283.     tst.l    d0
  284.     bne.s    unit_ready
  285.  
  286.     move.l    d2,d0
  287.     bsr.w    InitUnit
  288.     tst.l    d0
  289.     beq.s    open_err
  290.  
  291. unit_ready
  292.     move.l    d0,a3
  293.     move.l    d0,IO_UNIT(a2)
  294.  
  295.     addq.w    #1,UNIT_OPENCNT(a3)
  296.     addq.w    #1,LIB_OPENCNT(a6)
  297.     and.b    #~LIBF_DELEXP,LIB_FLAGS(a6)
  298.     moveq    #0,d0
  299.  
  300. open_exit
  301.     movem.l    (sp)+,d2/a2-a4
  302.     rts
  303.  
  304. open_err
  305.     moveq    #IOERR_OPENFAIL,d0
  306.     move.b    d0,IO_ERROR(a2)
  307.     bra.s    open_exit
  308.  
  309. ;
  310. ; close routine, entry: a6=devBase, a1=IORequest
  311. ; return: d0=SegList if device no longer in use, else zero
  312. ;
  313. Close    movem.l    a2-a3,-(sp)
  314.     move.l    a1,a2
  315.  
  316.     move.l    IO_UNIT(a2),a3
  317.  
  318.     moveq    #-1,d0
  319.     move.l    d0,IO_DEVICE(a2)
  320.     move.l    d0,IO_UNIT(a2)
  321.  
  322.     subq.w    #1,UNIT_OPENCNT(a3)
  323.     bne.s    do_close
  324.     bsr.w    ExpungeUnit
  325.  
  326. do_close
  327.     moveq    #0,d0
  328.     subq.w    #1,LIB_OPENCNT(a6)
  329.     bne.s    .100
  330.     btst    #LIBB_DELEXP,LIB_FLAGS(a6)
  331.     beq.s    .100
  332.     bsr.s    Expunge
  333.  
  334. .100:    movem.l    (sp)+,a2-a3
  335.     rts
  336.  
  337. ;
  338. ; expunge routine, entry: a6=devBase
  339. ; return: d0=SegList if device no longer in use, else zero
  340. ;
  341. Expunge    tst.w    LIB_OPENCNT(a6)
  342.     beq.s    .200
  343.     or.b    #LIBF_DELEXP,LIB_FLAGS(a6)
  344.     moveq    #0,d0
  345.     rts
  346. .200:    movem.l    a4-a6,-(sp)
  347.     move.l    a6,a4
  348.     move.l    4.w,a6
  349.     move.l    crd_SegList(a4),a5
  350.     move.l    a4,a1
  351.     lib    Remove
  352.  
  353. ;
  354. ; send termination message to dos caller process
  355. ;
  356.     suba.l    a1,a1
  357.     move.l    a4,a6
  358.     bsr.w    SendDosCallerRequest
  359.  
  360.     move.l    crd_DosCallerPort(a4),a1
  361.     moveq    #MP_SIZE,d0
  362.     move.l    4.w,a6
  363.     jsr    _LVOFreeMem(a6)
  364.  
  365.     move.l    crd_DosLib(a4),a1
  366.     lib    CloseLibrary
  367.  
  368.     move.l    crd_IntuitionBase(a4),a1
  369.     lib    CloseLibrary
  370.  
  371.     move.l    a4,a1
  372.     moveq    #0,d0
  373.     moveq    #0,d1
  374.     move.w    LIB_NEGSIZE(a4),d0
  375.     move.w    LIB_POSSIZE(a4),d1
  376.     sub.l    d0,a1
  377.     add.l    d1,d0
  378.     lib    FreeMem
  379.     move.l    a5,d0
  380.     movem.l    (sp)+,a4-a6
  381.     rts
  382.  
  383. ;
  384. ; find unit with a given unit number
  385. ; inputs: a6=DevBase, d0=UnitNum
  386. ; returns: d0=pointer to unit or zero if not found
  387. FindUnit
  388.     move.l    crd_UnitList(a6),a0
  389. .00    move.l    (a0),d1
  390.     beq.s    .01
  391.     cmp.w    crdu_UnitNum-crdu_Link(a0),d0
  392.     beq.s    .02
  393.     move.l    d1,a0
  394.     bra.s    .00
  395. .01    moveq    #0,d0
  396.     rts
  397. .02    lea    -crdu_Link(a0),a0
  398.     move.l    a0,d0
  399.     rts
  400.  
  401. ;
  402. ; initialize an unit. a6=DevBase, d2=unitnum
  403. ;
  404. InitUnit
  405.     movem.l    d2-d4/a3,-(sp)
  406.  
  407.     move.l    #crdu_Sizeof,d0
  408.     move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  409.     move.l    a6,-(sp)
  410.     move.l    4.w,a6
  411.     lib    AllocMem
  412.     move.l    (sp)+,a6
  413.     tst.l    d0
  414.     beq.s    init_u9
  415.     move.l    d0,a3
  416.     move.w    d2,crdu_UnitNum(a3)
  417.  
  418. ; create filename for FDEV-file
  419.     movem.l    a2-a3/a6,-(sp)
  420.     lea    formatstr(pc),a0
  421.     lea    crdu_UnitNum(a3),a1
  422.     lea    putch(pc),a2
  423.     lea    crdu_FileName(a3),a3
  424.     move.l    4.w,a6
  425.     lib    RawDoFmt
  426.     movem.l    (sp)+,a2-a3/a6
  427.  
  428. ;
  429. ; (encryption key is asked from the user and initialized
  430. ; in DosCallerProc if crdu_KeyValid is false...)
  431. ;
  432.  
  433.     lea    crd_UnitList(a6),a0
  434.     lea    crdu_Link(a3),a1
  435.  
  436.     move.l    a6,-(sp)
  437.     move.l    4.w,a6
  438.     lib    AddHead
  439.     move.l    (sp)+,a6
  440.  
  441.     move.l    a3,d0
  442.  
  443. init_u9    movem.l    (sp)+,d2-d4/a3
  444.     rts
  445.  
  446. putch    move.b    d0,(a3)+
  447.     rts
  448.  
  449. formatstr    dc.b    'CRDEV%d:',0
  450.  
  451.     even
  452. ;
  453. ; expunge an unit. a3=unit, a6=device
  454. ;
  455. ExpungeUnit
  456. ;
  457. ; request dos caller process to close the file. we give it a fake
  458. ; iorequest with io_Command set to CMD_RESET. we use the crdu_FileName
  459. ; field of the unit structure to store that iorequest (it is not used
  460. ; anymore anyway...)
  461. ;
  462.     lea    crdu_FileName(a3),a1
  463.     move.l    a3,IO_UNIT(a1)            this is important
  464.     move.w    #CMD_RESET,IO_COMMAND(a1)
  465.     bsr.w    SendDosCallerRequest
  466.  
  467.     move.l    a6,-(sp)
  468.     move.l    4.w,a6
  469.  
  470.     lea    crdu_Link(a3),a1
  471.     lib    Remove
  472.  
  473.     move.l    a3,a1
  474.     move.l    #crdu_Sizeof,d0
  475.     lib    FreeMem
  476.  
  477.     move.l    (sp)+,a6
  478.     rts
  479.  
  480. ;
  481. ; a1=IORequest, a6=Device
  482. ;
  483. BeginIO    movem.l    d2/a2-a3,-(sp)    
  484.     move.l    a1,a2
  485.     clr.b    IO_ERROR(a2)
  486.     move.l    IO_UNIT(a2),a3
  487.     move.w    IO_COMMAND(a2),d2
  488.     and.w    #$7fff,d2
  489.     cmp.w    #TD_LASTCOMM,d2
  490.     bcc.s    invalid_cmd
  491.  
  492. ;beginio_immediate
  493. ;PerformIO    ; a2=IORequest, a3=Unit, a6=Device
  494.     add.w    d2,d2
  495.     lea    DevCmdTable(pc),a0
  496.     add.w    d2,a0
  497.     add.w    (a0),a0
  498.     jsr    (a0)
  499.  
  500. beginio_exit
  501.     movem.l    (sp)+,d2/a2-a3
  502.     rts
  503.  
  504. invalid_cmd
  505.     move.b    #IOERR_NOCMD,IO_ERROR(a1)
  506.     bra.s    beginio_exit
  507.  
  508. ; you can't abort this
  509. AbortIO    moveq    #IOERR_NOCMD,d0
  510.     rts
  511.  
  512. InvalidParams
  513.     move.b    #IOERR_BADLENGTH,IO_ERROR(a1)
  514.     bra.b    TermIO
  515.  
  516.     ; a1=IORequest, a6=Device
  517. Invalid    move.b    #IOERR_NOCMD,IO_ERROR(a1)
  518.     ; fall to TermIO
  519. DoNothing
  520.     clr.l    IO_ACTUAL(a1)
  521. TermIO        ; a1=IORequest, a3=Unit, a6=Device
  522. ;termio_immediate
  523.     btst    #IOB_QUICK,IO_FLAGS(a1)
  524.     bne.s    termio_exit
  525.  
  526.     move.l    a6,-(sp)
  527.     move.l    4.w,a6
  528.     lib    ReplyMsg
  529.     move.l    (sp)+,a6
  530.  
  531. termio_exit
  532.     rts
  533.  
  534. ;
  535. ; here are the device command routines
  536. ;  a1=a2=IORequest
  537. ;  a3=Unit
  538. ;  a6=Device
  539. ;
  540.  
  541. DoGetDriveType
  542.     moveq    #1,d0            make it look like 3.5"
  543.     move.l    d0,IO_ACTUAL(a1)
  544.     bra.b    TermIO
  545.  
  546. ;
  547. ; actually any number will do,
  548. ; this device really doesn't even know it's size...
  549. ;
  550. DoGetNumTracks
  551.     move.l    #80,IO_ACTUAL(a1)
  552.     bra.b    TermIO
  553.  
  554. ;
  555. ; CMD_RESET, clears password
  556. ;
  557. ResetPassword
  558.     lea    crdu_KeySched(a3),a0
  559.     moveq    #(KS_SIZE/4)-1,d1
  560.     moveq    #0,d0
  561. .1    move.l    d0,(a0)+
  562.     dbf    d1,.1
  563.     clr.b    crdu_KeyValid(a3)
  564.     bra.b    TermIO
  565.  
  566. ;
  567. ; this does not work exactly like trackdisk TD_MOTOR but hopefully
  568. ; the file system doesn't mind...
  569. ;
  570. DoMotor    moveq    #0,d0
  571.     tst.l    crdu_FileHandle(a3)
  572.     sne    d0
  573.     move.l    d0,IO_ACTUAL(a1)
  574.     tst.l    IO_LENGTH(a1)
  575.     bne.s    .01
  576.     move.b    #CMD_RESET,IO_COMMAND+1(a1)
  577.     bsr.s    SendDosCallerRequest    request to close the file
  578.     move.b    #TD_MOTOR,IO_COMMAND+1(a2)
  579. .01    move.l    a2,a1
  580.     bra.b    TermIO
  581.  
  582. DoRead
  583. DoWrite    ;check that IO_OFFSET and IO_LENGTH are divisible by BLOCKSIZE (512)
  584.     move.l    IO_OFFSET(a1),d0
  585.     and.w    #BLOCKSIZE-1,d0
  586.     bne.b    InvalidParams
  587.     move.l    IO_LENGTH(a1),d0
  588.     and.w    #BLOCKSIZE-1,d0
  589.     bne.w    InvalidParams
  590.  
  591.     bsr.s    SendDosCallerRequest
  592.     move.l    a2,a1
  593.     bra.b    TermIO
  594.  
  595. ;
  596. ; send requests to DosCallerProc
  597. ;
  598. SendDosCallerRequest
  599.     movem.l    d5/a2/a5-a6,-(sp)
  600.     move.l    a1,d5
  601.  
  602.     move.l    a6,a5
  603.  
  604.     moveq    #MN_SIZE+MP_SIZE,d0
  605.     move.l    #MEMF_CLEAR!MEMF_PUBLIC,d1
  606.     move.l    4.w,a6
  607.     lib    AllocMem
  608.     tst.l    d0
  609.     beq.s    sendreq_end
  610.     move.l    d0,a2
  611.  
  612.     move.l    d5,LN_NAME(a2)
  613.  
  614.     moveq    #-1,d0
  615.     lib    AllocSignal
  616.     move.b    d0,MN_SIZE+MP_SIGBIT(a2)
  617.     bmi.s    sendreq_freemsg
  618.  
  619.     suba.l    a1,a1
  620.     lib    FindTask
  621.     move.l    d0,MN_SIZE+MP_SIGTASK(a2)
  622.  
  623.     lea    MN_SIZE(a2),a0
  624.     move.l    a0,MN_REPLYPORT(a2)
  625.  
  626.     lea    MN_SIZE+MP_MSGLIST(a2),a0
  627.     NEWLIST    a0
  628.  
  629.     move.l    crd_DosCallerPort(a5),a0
  630.     move.l    a2,a1
  631.     lib    PutMsg
  632.     lea    MN_SIZE(a2),a0
  633.     lib    WaitPort    
  634.  
  635.     moveq    #0,d0
  636.     move.b    MN_SIZE+MP_SIGBIT(a2),d0
  637.     lib    FreeSignal
  638.  
  639. sendreq_freemsg
  640.     move.l    a2,a1
  641.     moveq    #MN_SIZE+MP_SIZE,d0
  642.     lib    FreeMem
  643. sendreq_end
  644.     movem.l    (sp)+,d5/a2/a5-a6
  645.     rts
  646.  
  647. ;
  648. ; the dos caller process keeps DosBase in d7
  649. ; this macro is used to call DOS
  650. ;
  651. calldos    macro
  652.     exg    d7,a6
  653.     lib    \1
  654.     exg    d7,a6
  655.     endm
  656.  
  657. ;
  658. ; the dos caller process. only this process uses unit crdu_FileHandle fields
  659. ;
  660.  
  661. ; a fake seglist for CreateProc()
  662.     cnop    0,4
  663.     dc.l    20
  664. doscallerseglist
  665.     dc.l    0
  666.  
  667. doscaller_start
  668.     suba.l    a1,a1
  669.     move.l    4.w,a6
  670.     lib    FindTask
  671.     move.l    d0,a3
  672.     lea    pr_MsgPort(a3),a0
  673.     lib    WaitPort        wait for startup message
  674.     move.l    d0,a1
  675.     move.l    d0,a2
  676.     lib    Remove            remove the message from port
  677.     move.l    LN_NAME(a2),a5        get device base address
  678.     move.l    crd_DosLib(a5),d7    get DosBase
  679.     move.l    crd_IntuitionBase(a5),d6
  680.     move.l    crd_DosCallerPort(a5),a5    get message port address
  681.  
  682.     move.l    a3,MP_SIGTASK(a5)
  683.     moveq    #-1,d0
  684.     lib    AllocSignal
  685.     move.b    d0,MP_SIGBIT(a5)
  686.     clr.b    MP_FLAGS(a5)        set flags to PA_SIGNAL
  687.  
  688.     bra.s    proc_msgloop
  689.  
  690. proc_wait
  691.     moveq    #0,d0
  692.     move.b    MP_SIGBIT(a5),d1
  693.     bset    d1,d0
  694.     lib    Wait
  695.  
  696. proc_msgloop
  697.     move.l    a5,a0
  698.     lib    GetMsg
  699.     tst.l    d0
  700.     beq.s    proc_wait
  701.     move.l    d0,a4
  702.     move.l    LN_NAME(a4),d0
  703.     beq.w    quit_proc
  704.     move.l    d0,a3            get IORequest pointer to a3
  705.     move.l    IO_UNIT(a3),a2        get unit pointer to a2
  706.     cmp.w    #CMD_RESET,IO_COMMAND(a3)
  707.     beq.w    proc_reset        this doesn't need a valid key
  708.  
  709.     tst.b    crdu_KeyValid(a2)
  710.     bne.b    key_valid
  711. ;
  712.     bsr.w    AskPassword
  713. ;
  714.  
  715. key_valid
  716.     move.w    IO_COMMAND(a3),d0
  717.     and.w    #$7fff,d0        mask out EXTCOM flag bit
  718.     cmp.w    #CMD_RESET,d0        request to close file ?
  719.     beq.w    proc_reset
  720.     cmp.w    #CMD_READ,d0        if not read then write
  721.     bne.b    do_write        write may be CMD_WRITE or TD_FORMAT
  722.  
  723.     bsr.w    openfile
  724.     tst.l    d0
  725.     beq.w    proc_error
  726.  
  727.     bsr.w    seekfile
  728.     tst.l    d0
  729.     bmi.w    proc_error
  730. ;
  731. ; read
  732. ;
  733.     move.l    crdu_FileHandle(a2),d1
  734.     move.l    IO_DATA(a3),d2
  735.     move.l    IO_LENGTH(a3),d3
  736.     calldos    Read
  737.     tst.l    d0
  738.     bmi.w    proc_error
  739.     move.l    d0,IO_ACTUAL(a3)
  740.     move.l    d0,d3
  741. ;
  742. ; decrypt
  743. ;
  744.     move.l    d6,-(sp)
  745.     move.l    #BLOCKSIZE,d5
  746.     move.l    IO_OFFSET(a3),d6
  747.  
  748. decrypt_loop
  749.     move.l    d6,crdu_IVec(a2)
  750.     move.l    d6,crdu_IVec+4(a2)
  751.  
  752.     add.l    d5,d6
  753.  
  754.     clr.l    -(sp)        ;decrypt
  755.     pea    crdu_IVec(a2)
  756.     pea    crdu_KeySched(a2)
  757.     move.l    d5,-(sp)
  758.     move.l    d2,-(sp)
  759.     move.l    d2,-(sp)
  760.     bsr.w    _idea_cbc_encrypt
  761.     lea    6*4(sp),sp
  762.     add.l    d5,d2
  763.     sub.l    d5,d3
  764.     bgt.b    decrypt_loop
  765.     move.l    (sp)+,d6
  766.     bra.b    proc_replymsg
  767.  
  768. do_write
  769.     bsr.w    openfile
  770.     tst.l    d0
  771.     beq.w    proc_error
  772.  
  773.     bsr.w    seekfile
  774.     tst.l    d0
  775.     bmi.b    proc_error
  776.  
  777.     move.l    d6,-(sp)
  778.     move.l    #BLOCKSIZE,d5
  779.     move.l    IO_DATA(a3),d2
  780.     move.l    IO_LENGTH(a3),d3
  781.     clr.l    IO_ACTUAL(a3)
  782.     move.l    IO_OFFSET(a3),d6
  783.  
  784. encrypt_loop
  785.     move.l    d6,crdu_IVec(a2)
  786.     move.l    d6,crdu_IVec+4(a2)
  787.  
  788.     add.l    d5,d6
  789.  
  790.     pea    1        ;encrypt
  791.     pea    crdu_IVec(a2)
  792.     pea    crdu_KeySched(a2)
  793.     move.l    d5,-(sp)
  794.     pea    crdu_Buffer(a2)
  795.     move.l    d2,-(sp)
  796.     bsr.w    _idea_cbc_encrypt
  797.     lea    6*4(sp),sp
  798.  
  799.     move.l    crdu_FileHandle(a2),d1
  800.     lea    crdu_Buffer(a2),a0
  801.     movem.l    d2/d3,-(sp)
  802.     move.l    a0,d2
  803.     move.l    d5,d3
  804.     calldos    Write
  805.     movem.l    (sp)+,d2/d3
  806.     tst.l    d0
  807.     bmi.b    proc_error1
  808.  
  809.     add.l    d5,d2
  810.     add.l    d5,IO_ACTUAL(a3)
  811.     sub.l    d5,d3
  812.     bgt.b    encrypt_loop
  813.  
  814.     move.l    (sp)+,d6
  815.  
  816. proc_replymsg
  817.     move.l    a4,a1
  818.     lib    ReplyMsg
  819.     bra.w    proc_msgloop
  820.  
  821. proc_error1
  822.     move.l    (sp)+,d6
  823.  
  824. proc_error
  825.     calldos    IoErr
  826.     tst.b    d0
  827.     beq.s    .01
  828.     moveq    #-10,d0
  829. .01    move.b    d0,IO_ERROR(a3)
  830.     clr.l    IO_ACTUAL(a3)
  831.     bra.s    proc_replymsg
  832.  
  833. proc_reset
  834.     bsr.s    closefile
  835.     bra.s    proc_replymsg
  836.  
  837. openfile
  838.     move.l    crdu_FileHandle(a2),d0
  839.     bne.s    opf9
  840.     lea    crdu_FileName(a2),a0
  841.     move.l    a0,d1
  842.     move.l    #MODE_OLDFILE,d2
  843.     calldos    Open
  844.     move.l    d0,crdu_FileHandle(a2)
  845. opf9    rts
  846.  
  847. seekfile
  848.     move.l    crdu_FileHandle(a2),d1
  849.     move.l    IO_OFFSET(a3),d2
  850.     moveq    #OFFSET_BEGINNING,d3
  851.     calldos    Seek
  852.     rts
  853.  
  854. closefile
  855.     move.l    crdu_FileHandle(a2),d1
  856.     beq.s    clf9
  857.     calldos    Close
  858.     clr.l    crdu_FileHandle(a2)
  859. clf9    rts
  860.  
  861. ;
  862. ; quit the DosCaller process (just return from it...)
  863. ;
  864. quit_proc
  865.     move.l    a4,a1
  866.     jmp    _LVOReplyMsg(a6)
  867.  
  868. ;
  869. ; ask password from the user
  870. ;
  871. AskPassword
  872.     movem.l    d2/d3/a4/a3/a6,-(sp)
  873.  
  874.     moveq    #0,d2
  875.  
  876.     lea    crdu_Buffer(a2),a0
  877.     suba.l    a1,a1
  878.     move.l    #sc_BarHeight+1,d0
  879.     moveq    #WBENCHSCREEN,d1
  880.     move.l    d6,a6            ;intuitionbase
  881.     lib    GetScreenData
  882.     tst.l    d0
  883.     beq.b    .0
  884.  
  885.     move.b    crdu_Buffer+sc_BarHeight(a2),d2
  886.  
  887. .0    lea    NewWin(pc),a0
  888.     lea    crdu_Buffer(a2),a1
  889.     moveq    #nw_SIZEOF,d0
  890.     move.l    4.w,a6
  891.     lib    CopyMem
  892.  
  893.     add.w    d2,crdu_Buffer+nw_Height(a2)
  894.  
  895.     move.l    a2,-(sp)
  896.     lea    passwd_format(pc),a0
  897.     lea    crdu_UnitNum(a2),a1
  898.     lea    crdu_Buffer+400(a2),a3
  899.     lea    putch(pc),a2
  900.     lib    RawDoFmt
  901.     move.l    (sp)+,a2
  902.  
  903.     move.l    d6,a6
  904.     lea    crdu_Buffer(a2),a0
  905.     lib    OpenWindow
  906.     tst.l    d0
  907.     beq.w    askpw_end
  908.     move.l    d0,a4
  909.  
  910.     move.l    a2,-(sp)
  911.     move.l    a4,a0
  912.     lea    crdu_Buffer+400(a2),a1
  913.     lea    -1,a2
  914.     lib    SetWindowTitles
  915.     move.l    (sp)+,a2
  916.  
  917. enter_pass
  918.     lea    enterpass_txt(pc),a0
  919.     moveq    #10,d0
  920.     moveq    #8,d1
  921.     bsr.w    showtext
  922.  
  923.     bsr.w    get_input_line
  924.  
  925.     lea    crdu_Buffer(a2),a0
  926.     move.l    a0,d0
  927.     lea    crdu_Buffer+128(a2),a1
  928. .1    move.b    (a0)+,(a1)+        ;make a copy of the passphrase
  929.     bne.b    .1
  930.  
  931.     suba.l    d0,a0
  932.     cmpa.w    #11,a0            ;minimum passphrase length 10 chars
  933.     bcs.b    too_short
  934.  
  935.     lea    verifypass_txt(pc),a0
  936.     moveq    #10,d0
  937.     moveq    #8,d1
  938.     bsr.w    showtext
  939.  
  940.     bsr.w    get_input_line
  941.  
  942.     lea    crdu_Buffer(a2),a0
  943.     lea    crdu_Buffer+128(a2),a1
  944. .2    cmpm.b    (a0)+,(a1)+
  945.     bne.b    verify_fail
  946.     tst.b    -1(a0)
  947.     bne.b    .2
  948. ;
  949. ; verify ok
  950. ;
  951.     movea.l    a4,a0
  952.     movea.l    d6,a6
  953.     lib    CloseWindow
  954.  
  955.     lea    crdu_Buffer+256(a2),a0
  956.     clr.l    (a0)+
  957.     clr.l    (a0)+
  958.     clr.l    (a0)+
  959.     clr.l    (a0)+
  960.  
  961.     lea    crdu_Buffer(a2),a0
  962.     lea    crdu_Buffer+256+16(a2),a3
  963. passwd_l1
  964.     lea    crdu_Buffer+256(a2),a1
  965. passwd_loop
  966.     move.b    (a0)+,d0
  967.     beq.b    do_key_sched
  968.     add.b    d0,(a1)+
  969.     cmpa.l    a3,a1
  970.     bcs.b    passwd_loop
  971.     bra.b    passwd_l1
  972.  
  973. do_key_sched
  974.     pea    crdu_KeySched(a2)
  975.     pea    crdu_Buffer+256(a2)
  976.     bsr.w    _idea_key_schedule
  977.     addq.l    #8,sp
  978.  
  979. ;
  980. ; remove password from memory
  981. ;
  982.     lea    crdu_Buffer(a2),a0
  983.     moveq    #0,d0
  984.     moveq    #(512/4)-1,d1
  985. clr2_loop
  986.     move.l    d0,(a0)+
  987.     dbf    d1,clr2_loop
  988.  
  989.     st    crdu_KeyValid(a2)
  990.  
  991. askpw_end
  992.     movem.l    (sp)+,d2/d3/a3/a4/a6
  993.     rts
  994.  
  995. too_short
  996.     lea    tooshort_txt(pc),a0
  997.     bra.b    fail_comm
  998.  
  999. verify_fail
  1000.     lea    verifyfail_txt(pc),a0
  1001.  
  1002. fail_comm
  1003.     moveq    #10,d0
  1004.     moveq    #8,d1
  1005.     bsr.w    showtext
  1006.  
  1007.     move.l    wd_WScreen(a4),a0
  1008.     move.l    d6,a6
  1009.     lib    DisplayBeep
  1010.  
  1011.     move.l    d7,a6
  1012.     move.l    #2*50,d1    ;2 seconds
  1013.     lib    Delay
  1014.     bra.w    enter_pass
  1015.  
  1016. get_input_line
  1017.     lea    crdu_Buffer(a2),a3
  1018.  
  1019. msgloop    move.l    wd_UserPort(a4),a0
  1020.     move.l    4.w,a6
  1021.     lib    WaitPort
  1022.     move.l    wd_UserPort(a4),a0
  1023.     lib    GetMsg
  1024.     tst.l    d0
  1025.     beq.b    msgloop
  1026.     move.l    d0,a1
  1027.     move.l    im_Class(a1),d2
  1028.     move.w    im_Code(a1),d3
  1029.     lib    ReplyMsg
  1030.     cmp.l    #VANILLAKEY,d2
  1031.     bne.s    msgloop
  1032.  
  1033.     cmp.b    #8,d3        ;backspace?
  1034.     beq.b    pw_del
  1035.     cmp.b    #127,d3        ;del?
  1036.     bne.b    no_del
  1037.  
  1038. pw_del    lea    crdu_Buffer(a2),a0
  1039.     cmp.l    a0,a3
  1040.     beq.b    do_beep        ;can't delete if no chars in buffer
  1041.  
  1042.     subq.l    #1,a3
  1043.     lea    space_txt(pc),a0
  1044.     bsr.b    point
  1045.     bra.b    msgloop
  1046.  
  1047. no_del    cmp.b    #13,d3        ;CR?
  1048.     beq.b    getline_done
  1049.  
  1050.     lea    crdu_Buffer+125(a2),a0
  1051.     cmp.l    a0,a3
  1052.     bcs.b    add_char
  1053.  
  1054. do_beep    move.l    wd_WScreen(a4),a0
  1055.     move.l    d6,a6
  1056.     lib    DisplayBeep
  1057.     bra.b    msgloop
  1058.  
  1059. add_char
  1060.     lea    point_txt(pc),a0
  1061.     bsr.b    point
  1062.  
  1063.     move.b    d3,(a3)+
  1064.     bra.b    msgloop
  1065.  
  1066. getline_done
  1067.     clr.b    (a3)
  1068.     moveq    #10,d0
  1069.     moveq    #20,d1
  1070.     lea    spaces_txt(pc),a0
  1071.     bsr.b    showtext
  1072.     moveq    #10,d0
  1073.     moveq    #28,d1
  1074.     lea    spaces_txt(pc),a0
  1075.     bsr.b    showtext
  1076.     moveq    #10,d0
  1077.     moveq    #36,d1
  1078.     lea    spaces_txt(pc),a0
  1079.     bsr.b    showtext
  1080.     moveq    #10,d0
  1081.     moveq    #44,d1
  1082.     lea    spaces_txt(pc),a0
  1083.     bra.b    showtext
  1084.  
  1085. ;
  1086. ;
  1087. ;
  1088. point    lea    crdu_Buffer(a2),a1
  1089.     suba.l    a3,a1
  1090.     move.l    a1,d0
  1091.     neg.l    d0
  1092.     move.l    d0,d1
  1093.     and.w    #%11111,d0
  1094.     lsr.w    #5,d1
  1095.     lsl.l    #3,d0
  1096.     add.w    #10,d0
  1097.     lsl.l    #3,d1
  1098.     add.w    #20,d1
  1099. ;    bra    showtext
  1100. ; drop to showtext
  1101.  
  1102. ;
  1103. ; text in a0..., x/y coords in d0/d1 (upper word must be zero)
  1104. ;
  1105. showtext
  1106.     swap    d0
  1107.     or.l    d0,d1
  1108.  
  1109.     move.l    a0,d0
  1110. ;
  1111. ; use the end of crdu_Buffer for an IntuiText structure
  1112. ;
  1113.     lea    crdu_Buffer+BLOCKSIZE-it_SIZEOF(a2),a0
  1114.     move.l    #(1<<24)!(0<<16)!(RP_JAM2<<8)!0,(a0)+    ;pens, drawmode
  1115.     move.l    d1,(a0)+            ;left, top
  1116.     lea    Topaz80(pc),a1
  1117.     move.l    a1,(a0)+        ;font
  1118.     move.l    d0,(a0)+        ;text
  1119.     clr.l    (a0)            ;next
  1120.     move.l    d6,a6            ;intutionbase
  1121.     move.l    wd_RPort(a4),a0
  1122.     lea    crdu_Buffer+BLOCKSIZE-it_SIZEOF(a2),a1
  1123.     moveq    #0,d0
  1124.     moveq    #0,d1
  1125.     move.b    wd_BorderLeft(a4),d0
  1126.     move.b    wd_BorderTop(a4),d1
  1127.     lib    PrintIText
  1128.     rts
  1129.  
  1130. NewWin    dc.w    100,100,300,70
  1131.     dc.b    -1,-1
  1132.     dc.l    VANILLAKEY
  1133.     dc.l    WINDOWDEPTH!WINDOWDRAG!ACTIVATE!SMART_REFRESH!NOCAREREFRESH
  1134.     dc.l    0
  1135.     dc.l    0
  1136.     dc.l    dev_name    ;title
  1137.     dc.l    0,0    ;no screen, no bitmap
  1138.     dc.w    0,0,0,0
  1139.     dc.w    WBENCHSCREEN
  1140.  
  1141. Topaz80    dc.l    topaz_name
  1142.     dc.w    8
  1143.     dc.b    FS_NORMAL
  1144.     dc.b    FPF_ROMFONT
  1145.  
  1146. topaz_name    dc.b    'topaz.font',0
  1147.  
  1148. enterpass_txt    dc.b    'Enter pass phrase    ',0
  1149. verifypass_txt    dc.b    'Retype pass phrase   ',0
  1150. verifyfail_txt    dc.b    'Pass phrases differ  ',0
  1151. tooshort_txt    dc.b    'Pass phrase too short',0
  1152. passwd_format    dc.b    'cryptdev unit #%d',0
  1153. point_txt    dc.b    '.',0
  1154. space_txt    dc.b    ' ',0
  1155. spaces_txt    dc.b    '                                 ',0
  1156.         even
  1157.  
  1158. ZSIZE        equ    108
  1159.  
  1160. ;-------------------------------------------------------------------------
  1161. ; Internal functions
  1162. ;-------------------------------------------------------------------------
  1163. ; macro: imul dea,dn , d7=scratch
  1164. ; Arg 1 accessed only once (can be (an)+) Handles zero value arguments.
  1165. ;
  1166.  
  1167. imul        macro
  1168.  
  1169.         move.w    \2,d7
  1170.         beq.b    .imul0
  1171.         mulu.w    \1,d7
  1172.         beq.b    .imul1
  1173.         move.w    d7,\2
  1174.         swap    d7
  1175.         sub.w    d7,\2
  1176.         moveq    #0,d7
  1177.         addx.w    d7,\2
  1178.         bra.b    .imul3
  1179.  
  1180. .imul0        move.w    \1,\2
  1181. .imul1        neg.w    \2
  1182.         addq.w    #1,\2
  1183. .imul3
  1184.         endm
  1185.  
  1186. ;-------------------------------------------------------------------------
  1187. ; word16 _mul_idea(word16 a,word16 b)
  1188. ;
  1189. ; Return a * b mod 65537
  1190.  
  1191. __mul_idea    move.l    d7,-(sp)
  1192.         move.w    10(sp),d0
  1193.  
  1194.         imul    14(sp),d0
  1195.  
  1196.         move.l    (sp)+,d7
  1197.         rts
  1198.  
  1199. ;-------------------------------------------------------------------------
  1200. ; word16 _inv_idea(word16 a)
  1201. ; d0 = inv(d0)
  1202. ;
  1203. ; Return multiplicative inverse of a mod 65537
  1204. ;
  1205.  
  1206. __inv_idea    move.w    6(sp),d0
  1207.  
  1208. inv        cmp.w    #2,d0        ; inv(0)=0,inv(1)=1
  1209.         bcs.b    .1
  1210.  
  1211.         cmp.w    #3,d0
  1212.         bcc.b    .2
  1213.  
  1214.         move.w    #32769,d0    ; inv(2)
  1215. .1        rts
  1216.  
  1217. .2        movem.l    d2-d5,-(sp)
  1218.         move.l    #$10001,d1    ; d1 = n1
  1219.         moveq    #1,d2        ; d2 = b2
  1220.         moveq    #0,d3        ; d3 = b1        
  1221.  
  1222. inv_loop    divu.w    d0,d1
  1223.         move.l    d1,d4
  1224.         swap    d4        ; r = d4
  1225.         tst.w    d4
  1226.         beq.b    inv_done
  1227.  
  1228.         move.w    d2,d5
  1229.         muls.w    d1,d5
  1230.         exg    d3,d2
  1231.         sub.l    d5,d2
  1232.         moveq    #0,d1
  1233.         move.w     d0,d1
  1234.         move.w    d4,d0
  1235.         bra.b    inv_loop
  1236.  
  1237. inv_done    tst.l    d2
  1238.         bpl.b    .1
  1239.  
  1240.         move.l    #$10001,d0
  1241.         add.l    d2,d0
  1242.         bra.b    .2
  1243.  
  1244. .1        move.l    d2,d0
  1245.  
  1246. .2        movem.l    (sp)+,d2-d5
  1247.         rts
  1248.  
  1249. ;-------------------------------------------------------------------------
  1250. ; _en_key_idea(a0=userkey,a1=subkey)
  1251. ;
  1252. ; Create 54-word encryption subkey from 8-word user key
  1253. ;
  1254.  
  1255. __en_key_idea    movem.l    4(sp),a0-a1
  1256.  
  1257. en_key_idea    movem.l    d2-d4,-(sp)
  1258.         move.l    (a0)+,(a1)+
  1259.         move.l    (a0)+,(a1)+
  1260.         move.l    (a0)+,(a1)+
  1261.         move.l    (a0)+,(a1)
  1262.  
  1263.         suba.w    #12,a1
  1264.  
  1265.         moveq    #47,d0
  1266.         moveq    #0,d1
  1267.         moveq    #14,d4
  1268.  
  1269. .1        move.w    d1,d2
  1270.         addq.w    #2,d2
  1271.         and.w    d4,d2
  1272.         move.w    0(a1,d2.w),d3
  1273.         swap    d3
  1274.         addq.w    #2,d2
  1275.         and.w    d4,d2
  1276.         move.w    0(a1,d2.w),d3
  1277.         lsr.l    #7,d3
  1278.         move.w    d3,16(a1,d1.w)
  1279.         addq.w    #2,d1
  1280.         move.w    d1,d2
  1281.         and.w    #16,d2
  1282.         adda.w    d2,a1
  1283.         and.w    d4,d1
  1284.         dbra    d0,.1
  1285.  
  1286.         movem.l    (sp)+,d2-d4
  1287.         rts
  1288.  
  1289. ;-------------------------------------------------------------------------
  1290. ; _de_key_idea(a0=subkey,a1=inverted_subkey)
  1291. ;
  1292. ; Invert 54-word subkey for idea decrypting
  1293. ;
  1294.  
  1295. __de_key_idea    movem.l    4(sp),a0-a1
  1296.  
  1297. de_key_idea    movem.l    d2-d3,-(sp)
  1298.  
  1299.         moveq    #96,d2
  1300.         moveq    #0,d3
  1301.         bra.b    e2
  1302.  
  1303. e1        move.l    8(a0,d2.w),-4(a1,d3.w)
  1304.  
  1305. e2        move.w    0(a0,d2.w),d0
  1306.         bsr.w    inv
  1307.         move.w    d0,0(a1,d3.w)
  1308.         move.l    2(a0,d2.w),d0
  1309.         neg.w    d0
  1310.         swap    d0
  1311.         neg.w    d0
  1312.         move.l    d0,2(a1,d3.w)
  1313.         move.w    6(a0,d2.w),d0
  1314.         bsr.w    inv
  1315.         move.w    d0,6(a1,d3.w)
  1316.         add.w    #12,d3
  1317.         sub.w    #12,d2
  1318.         bcc.b    e1
  1319.  
  1320.         move.l    2(a1),d0
  1321.         swap    d0
  1322.         move.l    d0,2(a1)
  1323.         move.l    98(a1),d0
  1324.         swap    d0
  1325.         move.l    d0,98(a1)
  1326.  
  1327.         movem.l    (sp)+,d2-d3
  1328.         rts
  1329.  
  1330. ;-------------------------------------------------------------------------
  1331. ; _cipher_idea(a0=src,a1=dest,a2=subkey)
  1332. ;
  1333. ; En/Decipher 4-word block from src to dest using 54-word subkey as key
  1334. ;
  1335.  
  1336. round        macro
  1337.         imul    (a0)+,d0
  1338.         add.w    (a0)+,d1        
  1339.         add.w    (a0)+,d2
  1340.  
  1341.         move.w    d3,d7
  1342.         beq.b    imul0
  1343.         mulu.w    (a0)+,d7
  1344.         beq.b    imul1
  1345.         move.w    d7,d3
  1346.         swap    d7
  1347.         sub.w    d7,d3
  1348.         moveq    #0,d7
  1349.         addx.w    d7,d3
  1350.         bra.b    imul3
  1351. imul0        move.w    (a0)+,d3
  1352. imul1        neg.w    d3
  1353.         addq.w    #1,d3
  1354. imul3
  1355.  
  1356.         move.w    d0,d4
  1357.         eor.w    d2,d4
  1358.  
  1359.  
  1360.         move.w    d4,d7
  1361.         beq.b    imul00
  1362.         mulu.w    (a0)+,d7
  1363.         beq.b    imul01
  1364.         move.w    d7,d4
  1365.         swap    d7
  1366.         sub.w    d7,d4
  1367.         moveq    #0,d7
  1368.         addx.w    d7,d4
  1369.         bra.b    imul03
  1370. imul00        move.w    (a0)+,d4
  1371. imul01        neg.w    d4
  1372.         addq.w    #1,d4
  1373. imul03
  1374.  
  1375.  
  1376.         move.w    d1,d5
  1377.         eor.w    d3,d5
  1378.         add.w    d4,d5
  1379.         imul    (a0)+,d5
  1380.         move.w    d5,d6
  1381.         add.w    d4,d6
  1382.  
  1383.         eor.w    d5,d0
  1384.         move.w    d1,d4
  1385.         move.w    d2,d1
  1386.         eor.w    d5,d1
  1387.         move.w    d4,d2
  1388.         eor.w    d6,d2
  1389.         eor.w    d6,d3
  1390.         endm
  1391.  
  1392. __cipher_idea    move.l    a2,-(sp)
  1393.         movem.l    8(sp),a0-a2
  1394.         bsr.b    cipher_idea
  1395.         move.l    (sp)+,a2
  1396.         rts
  1397.  
  1398. cipher_idea    movem.l    d2-d7,-(sp)
  1399.         movem.w    (a0),d0-d3
  1400.         movea.l    a2,a0
  1401.  
  1402.         ifnd    UNROLL
  1403.         moveq    #7,d6
  1404. cipher_loop    swap    d6
  1405.         round
  1406.         swap    d6
  1407.         dbra    d6,cipher_loop
  1408.         endc
  1409.  
  1410.         ifd    UNROLL
  1411.         round
  1412.         round
  1413.         round
  1414.         round
  1415.         round
  1416.         round
  1417.         round
  1418.         round
  1419.         endc
  1420.  
  1421.         move.w    d0,d7
  1422.         beq.b    imul000
  1423.         mulu.w    (a0)+,d7
  1424.         beq.b    imul001
  1425.         move.w    d7,d0
  1426.         swap    d7
  1427.         sub.w    d7,d0
  1428.         moveq    #0,d7
  1429.         addx.w    d7,d0
  1430.         bra.b    imul003
  1431.  
  1432. imul000        move.w    (a0)+,d0
  1433. imul001        neg.w    d0
  1434.         addq.w    #1,d0
  1435. imul003
  1436.  
  1437.         exg    d1,d2
  1438.         add.w    (a0)+,d1
  1439.         add.w    (a0)+,d2
  1440.         imul    (a0)+,d3
  1441.  
  1442.         movem.w    d0-d3,(a1)
  1443.         movem.l    (sp)+,d2-d7
  1444.         rts
  1445.  
  1446. ;-------------------------------------------------------------------------
  1447. ; User callable routines 
  1448. ;-------------------------------------------------------------------------
  1449. ; idea_key_schedule(word16 *uk, word16 *ks)
  1450. ;
  1451. ; Create en/decryption keys from 8-word user key uk to 108-word key 
  1452. ; schedule ks.
  1453. ;
  1454.  
  1455. _idea_key_schedule
  1456.         movem.l    4(sp),a0-a1
  1457.         bsr.w    en_key_idea
  1458.         movea.l    8(sp),a0
  1459.         movea.l    a0,a1
  1460.         adda.w    #ZSIZE,a1
  1461.         bra.w    de_key_idea
  1462.  
  1463. ;-------------------------------------------------------------------------
  1464. ; idea_ebc_encrypt(word16 *src,word16 *dst,word16 *ks,int mode)
  1465. ;
  1466. ; En/decrypt 4 word (8-byte) block from src to dst using electronic code
  1467. ; book mode.
  1468. ;
  1469.  
  1470. _idea_ebc_encrypt
  1471.         move.l    a2,-(sp)
  1472.         movem.l    8(sp),a0-a2/d0
  1473.         tst.l    d0
  1474.         bne.w    e1
  1475.         adda.w    #ZSIZE,a2
  1476.         bsr.w    cipher_idea
  1477.         movea.l    (sp)+,a2
  1478.         rts
  1479.  
  1480. ;-------------------------------------------------------------------------
  1481. ; idea_cbc_encrypt(word16 *src, word16 *dst, int len, word16 *ks,
  1482. ;   word16 *ivec,int mode)
  1483. ;
  1484. ; Encrypt (mode != 0) or decrypt (mode == 0) src to dst in cipher block 
  1485. ; chaining mode. Len must be multiple of 8 bytes. Ivec contains final
  1486. ; vector at return.
  1487. ;
  1488.  
  1489. _idea_cbc_encrypt
  1490.         movem.l    a2-a5/d2-d4,-(sp)
  1491.  
  1492.         lea    32(sp),a0
  1493.         move.l    (a0)+,a3    ; src
  1494.         move.l    (a0)+,a4    ; dst
  1495.         move.l    (a0)+,d2    ; len
  1496.         move.l    (a0)+,a2    ; ks
  1497.         move.l    (a0)+,a5    ; ivec
  1498.  
  1499.         tst.l    (a0)        ; mode?
  1500.         beq.b    cbc_decrypt
  1501.  
  1502. cbc_en_loop    move.l    (a3)+,d3    ; get data to encrypt
  1503.         move.l    (a3)+,d4
  1504.         eor.l    d3,(a5)        ; eor with ivec        
  1505.         eor.l    d4,4(a5)
  1506.  
  1507.         movea.l    a5,a0        ; cipher ivec to dst
  1508.         movea.l    a4,a1
  1509.         bsr.w    cipher_idea
  1510.         move.l    (a4)+,(a5)    ; copy cipher to ivec
  1511.         move.l    (a4)+,4(a5)
  1512.  
  1513.         subq    #8,d2
  1514.         bhi.b    cbc_en_loop
  1515.         
  1516. cbc_exit    movem.l    (sp)+,a2-a5/d2-d4
  1517.         rts
  1518.  
  1519. cbc_decrypt    adda.w    #ZSIZE,a2    ; decrypt key
  1520.  
  1521. cbc_de_loop    move.l    (a3)+,d3    ; store cipher data (next ivec)
  1522.         move.l    (a3)+,d4
  1523.  
  1524.         lea    -8(a3),a0    ; decrypt to src
  1525.         movea.l    a4,a1
  1526.         bsr.w    cipher_idea
  1527.  
  1528.         move.l    (a5)+,d0    ; swap next/curr ivec
  1529.         move.l    (a5),d1
  1530.         move.l    d4,(a5)
  1531.         move.l    d3,-(a5)
  1532.  
  1533.         eor.l    d0,(a4)+    ; eor deciphered with ivec
  1534.         eor.l    d1,(a4)+
  1535.  
  1536.         subq    #8,d2
  1537.         bhi.b    cbc_de_loop
  1538.  
  1539.         bra.b    cbc_exit
  1540.  
  1541.  
  1542.  
  1543. ;
  1544. ; label for RT_ENDSKIP -- note that this must be in the same hunk as RomTag
  1545. ;
  1546. EndSkip
  1547.  
  1548.     end
  1549.